﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CubeDAL;
using SysInfo;

namespace CrossQuery
{
    public class FreeQuery : Query
    {
        /// <summary>
        /// sql should use {0} {1}... to insert parameter
        /// </summary>
        private string sql;
        /// <summary>
        /// Display name of this cross query
        /// </summary>
        private string display_name;
        /// <summary>
        /// List of parameter display names 
        /// </summary>
        private List<string> param_dp_list;
        /// <summary>
        /// List of parameter objects, the son-class of IType
        /// </summary>
        private List<IType> param_obj_list;
        /// <summary>
        /// List of outputing database field names 
        /// </summary>
        private List<string> output_db_list;
        /// <summary>
        /// List of outputing display names
        /// </summary>
        private List<string> output_dp_list;
        /// <summary>
        /// Indicate the type of chart, {pie, bar}
        /// </summary>
        private string chart_type;

        public FreeQuery()
        {
            Initial();
        }

        public string this[string parameter_display_name]
        {
            get
            {
                for (int i = 0; i < param_dp_list.Count(); ++i)
                {
                    if (param_dp_list[i] == parameter_display_name)
                        return param_obj_list[i].ToString();
                }
                return "";
            }
            set 
            {
                for (int i = 0; i < param_dp_list.Count(); ++i)
                {
                    if (param_dp_list[i] == parameter_display_name)
                        param_obj_list[i].Value = value;
                }
            }
        }

        public List<string> ParameterDisplayNames
        {
            get { return param_dp_list; }
        }

        public List<IType> ParameterTypes
        {
            get { return param_obj_list; }
        }

        public List<string> OutputFieldDisplayNames
        {
            get { return output_dp_list; }
        }

        public string DisplayName
        {
            get { return display_name; }
        }

        public string ChartType
        {
            get { return chart_type; }
        }

        public List<List<string>> Execute()
        { 
            string server = Constant.DB_SERVER;
            string database = Constant.DB_DATABASE;
            string user = Constant.DB_USER;
            string pwd = Constant.DB_PASSWORD;
            MySQLWrapper wrapper = new MySQLWrapper(server, database, user, pwd);
            return wrapper.Select(ToSQLCommand(), output_db_list.ToArray());
        }

        public void SetSQL(string sql)
        {
            this.sql = sql;
        }

        public void SetDisplayName(string display_name)
        {
            this.display_name = display_name;
        }

        public void SetChartType(string type)
        {
            chart_type = type;
        }

        public void AddParameter(string display_name, string obj_type)
        {
            param_dp_list.Add(display_name);
            param_obj_list.Add(TypeGenerator.getInstance(obj_type));
        }

        public void AddOutputDatabaseName(string field_name)
        {
            output_db_list.Add(field_name);
        }

        public void AddOutputDisplayName(string display_name)
        {
            output_dp_list.Add(display_name);
        }

        public string ToSQLCommand()
        { 
            object[] paras = new object[param_obj_list.Count()];
            for (int i = 0; i < param_obj_list.Count(); ++i)
            {
                paras[i] = param_obj_list[i].ToSQLString();
            }
            return String.Format(sql, paras);
        }

        private void Initial()
        {
            sql = "";
            param_dp_list = new List<string>();
            param_obj_list = new List<IType>();
            output_db_list = new List<string>();
            output_dp_list = new List<string>();
            chart_type = "";
        }
    }
}
